package api

import (
	"go-weiqi-system/config"
	"go-weiqi-system/internal/models"
	"go-weiqi-system/internal/utils"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

type AuthController struct {
	Config *config.Config
}

// Register 账号密码注册
func (ctrl *AuthController) Register(c *gin.Context) {
	var req struct {
		Phone    string `json:"phone" binding:"required"`
		Password string `json:"password" binding:"required"`
		Nickname string `json:"nickname"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		utils.Error(c, "参数错误")
		return
	}

	// 验证手机号
	if !utils.ValidatePhone(req.Phone) {
		utils.Error(c, "手机号格式不正确")
		return
	}

	// 验证密码
	if !utils.ValidatePassword(req.Password) {
		utils.Error(c, "密码长度不能少于6位")
		return
	}

	// 检查手机号是否已注册
	var count int64
	config.DB.Model(&models.User{}).Where("phone = ?", req.Phone).Count(&count)
	if count > 0 {
		utils.Error(c, "该手机号已被注册")
		return
	}

	// 密码加密
	hashedPassword, err := utils.HashPassword(req.Password)
	if err != nil {
		utils.Error(c, "密码加密失败")
		return
	}

	// 创建用户
	nickname := req.Nickname
	if nickname == "" {
		nickname = "用户" + req.Phone[len(req.Phone)-4:]
	}

	user := models.User{
		Phone:    req.Phone,
		Nickname: nickname,
		Status:   1,
	}

	if err := config.DB.Create(&user).Error; err != nil {
		utils.Error(c, "注册失败")
		return
	}

	// 保存密码（简化处理，实际应添加password字段）
	config.DB.Exec("UPDATE go_user SET openid = ? WHERE id = ?", hashedPassword, user.ID)

	// 生成token
	token, err := utils.GenerateToken(
		user.ID,
		"",
		user.Phone,
		user.Nickname,
		"",
		ctrl.Config.JWTSecret,
		ctrl.Config.JWTExpireHours,
	)
	if err != nil {
		utils.Error(c, "生成token失败")
		return
	}

	utils.Success(c, gin.H{
		"token": token,
		"user": gin.H{
			"id":       user.ID,
			"nickname": user.Nickname,
			"avatar":   user.Avatar,
			"phone":    user.Phone,
		},
	}, "注册成功")
}

// Login 账号密码登录
func (ctrl *AuthController) Login(c *gin.Context) {
	var req struct {
		Phone    string `json:"phone" binding:"required"`
		Password string `json:"password" binding:"required"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		utils.Error(c, "参数错误")
		return
	}

	// 验证手机号
	if !utils.ValidatePhone(req.Phone) {
		utils.Error(c, "手机号格式不正确")
		return
	}

	// 查询用户
	var user models.User
	if err := config.DB.Where("phone = ?", req.Phone).First(&user).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			utils.Error(c, "手机号未注册")
		} else {
			utils.Error(c, "查询失败")
		}
		return
	}

	// 检查用户状态
	if user.Status != 1 {
		utils.Error(c, "账号已被禁用，请联系管理员")
		return
	}

	// 验证密码（简化处理）
	var hashedPassword string
	config.DB.Raw("SELECT openid FROM go_user WHERE id = ?", user.ID).Scan(&hashedPassword)
	if hashedPassword == "" || !utils.CheckPassword(req.Password, hashedPassword) {
		utils.Error(c, "密码错误")
		return
	}

	// 生成token
	token, err := utils.GenerateToken(
		user.ID,
		"",
		user.Phone,
		user.Nickname,
		"",
		ctrl.Config.JWTSecret,
		ctrl.Config.JWTExpireHours,
	)
	if err != nil {
		utils.Error(c, "生成token失败")
		return
	}

	utils.Success(c, gin.H{
		"token": token,
		"user": gin.H{
			"id":       user.ID,
			"nickname": user.Nickname,
			"avatar":   user.Avatar,
			"phone":    user.Phone,
		},
	}, "登录成功")
}

// WxLogin 微信小程序登录
func (ctrl *AuthController) WxLogin(c *gin.Context) {
	var req struct {
		Code string `json:"code" binding:"required"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		utils.Error(c, "缺少code参数")
		return
	}

	// 检查微信配置
	if ctrl.Config.WechatAppID == "" || ctrl.Config.WechatSecret == "" {
		utils.Error(c, "微信配置未设置，请联系管理员")
		return
	}

	// 调用微信接口获取session_key和openid
	session, err := utils.Code2Session(ctrl.Config.WechatAppID, ctrl.Config.WechatSecret, req.Code)
	if err != nil {
		utils.Error(c, "微信登录失败："+err.Error())
		return
	}

	// 查询或创建用户
	var user models.User
	result := config.DB.Where("openid = ?", session.OpenID).First(&user)

	isNew := false
	if result.Error == gorm.ErrRecordNotFound {
		// 创建新用户
		user = models.User{
			OpenID:   session.OpenID,
			Nickname: "微信用户" + session.OpenID[len(session.OpenID)-6:],
			Status:   1,
		}
		if err := config.DB.Create(&user).Error; err != nil {
			utils.Error(c, "创建用户失败")
			return
		}
		isNew = true
	}

	// 检查用户状态
	if user.Status != 1 {
		utils.Error(c, "账号已被禁用，请联系管理员")
		return
	}

	// 生成token
	token, err := utils.GenerateToken(
		user.ID,
		"",
		user.Phone,
		user.Nickname,
		user.OpenID,
		ctrl.Config.JWTSecret,
		ctrl.Config.JWTExpireHours,
	)
	if err != nil {
		utils.Error(c, "生成token失败")
		return
	}

	utils.Success(c, gin.H{
		"token": token,
		"user": gin.H{
			"id":       user.ID,
			"nickname": user.Nickname,
			"avatar":   user.Avatar,
			"phone":    user.Phone,
		},
		"is_new": isNew,
	}, "登录成功")
}

// GetUserInfo 获取当前登录用户信息
func (ctrl *AuthController) GetUserInfo(c *gin.Context) {
	userID, _ := c.Get("user_id")

	var user models.User
	if err := config.DB.First(&user, userID).Error; err != nil {
		utils.Error(c, "用户不存在")
		return
	}

	utils.Success(c, gin.H{
		"id":                 user.ID,
		"nickname":           user.Nickname,
		"avatar":             user.Avatar,
		"phone":              user.Phone,
		"level_score":        user.LevelScore,
		"contribution_score": user.ContributionScore,
		"win_rate":           user.WinRate,
		"total_games":        user.TotalGames,
		"win_games":          user.WinGames,
	})
}

// UpdateUserInfo 更新用户信息
func (ctrl *AuthController) UpdateUserInfo(c *gin.Context) {
	userID, _ := c.Get("user_id")

	var req struct {
		Nickname string `json:"nickname"`
		Avatar   string `json:"avatar"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		utils.Error(c, "参数错误")
		return
	}

	updates := map[string]interface{}{}
	if req.Nickname != "" {
		updates["nickname"] = req.Nickname
	}
	if req.Avatar != "" {
		updates["avatar"] = req.Avatar
	}

	if err := config.DB.Model(&models.User{}).Where("id = ?", userID).Updates(updates).Error; err != nil {
		utils.Error(c, "更新失败")
		return
	}

	var user models.User
	config.DB.First(&user, userID)

	utils.Success(c, gin.H{
		"id":       user.ID,
		"nickname": user.Nickname,
		"avatar":   user.Avatar,
		"phone":    user.Phone,
	}, "更新成功")
}

// BindPhone 绑定手机号
func (ctrl *AuthController) BindPhone(c *gin.Context) {
	userID, _ := c.Get("user_id")

	var req struct {
		Phone string `json:"phone" binding:"required"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		utils.Error(c, "参数错误")
		return
	}

	// 验证手机号格式
	if !utils.ValidatePhone(req.Phone) {
		utils.Error(c, "手机号格式不正确")
		return
	}

	// 检查手机号是否已被绑定
	var count int64
	config.DB.Model(&models.User{}).
		Where("phone = ? AND id != ?", req.Phone, userID).
		Count(&count)

	if count > 0 {
		utils.Error(c, "该手机号已被其他账号绑定")
		return
	}

	if err := config.DB.Model(&models.User{}).Where("id = ?", userID).Update("phone", req.Phone).Error; err != nil {
		utils.Error(c, "绑定失败")
		return
	}

	utils.Success(c, gin.H{
		"phone": req.Phone,
	}, "绑定成功")
}

// DecryptPhone 解密微信手机号
func (ctrl *AuthController) DecryptPhone(c *gin.Context) {
	userID, _ := c.Get("user_id")

	var req struct {
		EncryptedData string `json:"encrypted_data" binding:"required"`
		IV            string `json:"iv" binding:"required"`
		SessionKey    string `json:"session_key"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		utils.Error(c, "参数错误")
		return
	}

	// 解密
	phoneInfo, err := utils.DecryptWechatData(req.EncryptedData, req.IV, req.SessionKey, ctrl.Config.WechatAppID)
	if err != nil {
		utils.Error(c, "解密失败："+err.Error())
		return
	}

	phone := phoneInfo.PhoneNumber

	// 检查手机号是否已被绑定
	var count int64
	config.DB.Model(&models.User{}).
		Where("phone = ? AND id != ?", phone, userID).
		Count(&count)

	if count > 0 {
		utils.Error(c, "该手机号已被其他账号绑定")
		return
	}

	// 绑定手机号
	if err := config.DB.Model(&models.User{}).Where("id = ?", userID).Update("phone", phone).Error; err != nil {
		utils.Error(c, "绑定失败")
		return
	}

	utils.Success(c, gin.H{
		"phone": phone,
	}, "绑定成功")
}
